{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Part 9 - এনক্রিপ্টড প্রোগ্রামগুলির পরিচয় (Intro to Encrypted Programs)\n",
    "\n",
    "বিশ্বাস করুন বা না করুন, এনক্রিপ্ট করা ডেটা দিয়ে গণনা করা সম্ভব। অন্য কথায়, একটি প্রোগ্রাম চালানো সম্ভব যেখানে প্রোগ্রামের **সমস্ত ভেরিয়েবল** **এনক্রিপ্টেড** ( _All of the variables in the program are encrypted_ )\n",
    "\n",
    "এই টিউটোরিয়ালে, আমরা এনক্রিপ্ট করা গণনার খুব প্রাথমিক সরঞ্জামগুলির মধ্য দিয়ে চলতে যাচ্ছি। বিশেষত, আমরা সিকিওর মাল্টি-পার্টির গণনা নামে পরিচিত একটি জনপ্রিয় পদ্ধতির উপর ফোকাস করতে যাচ্ছি। এই পাঠে, আমরা কীভাবে একটি এনক্রিপ্ট করা ক্যালকুলেটর তৈরি করতে শিখব যা এনক্রিপ্ট হওয়া সংখ্যায় গণনা সম্পাদন করতে পারে।\n",
    "\n",
    "Authors:\n",
    "- Andrew Trask - Twitter: [@iamtrask](https://twitter.com/iamtrask)\n",
    "- Théo Ryffel - GitHub: [@LaRiffle](https://github.com/LaRiffle)\n",
    "\n",
    "References: \n",
    "- Morten Dahl - [Blog](https://mortendahl.github.io) - Twitter: [@mortendahlcs](https://twitter.com/mortendahlcs)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "অনুবাদক:\n",
    "\n",
    "- Sourav Das - Twitter: [@adventuroussrv](https://twitter.com/adventuroussrv)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Step 1: সুরক্ষিত মাল্টি-পার্টির গণনা ব্যবহার করে এনক্রিপশন (Encryption Using Secure Multi-Party Computation)\n",
    "\n",
    "এসএমপিসি(SMPC) প্রথম নজরে \"এনক্রিপশন\" এর চেয়ে বরং এক অদ্ভুত রূপ। কোনও ভেরিয়েবল এনক্রিপ্ট করার জন্য পাবলিক / প্রাইভেট কী ব্যবহার করার পরিবর্তে প্রতিটি মান একাধিকতে বিভক্ত হয় shares, যার প্রতিটি একটি ব্যক্তিগত কী হিসাবে চালিত হয়। সাধারণত, এই shares 2 বা ততোধিক মালিকদের মাঝে বিতরণ করা হবে। সুতরাং, ভেরিয়েবলটি ডিক্রিপ্ট(decrypt the variable) করার জন্য, সমস্ত মালিকদের ডিক্রিপশন অনুমোদনের জন্য সম্মত হতে হবে। সংক্ষেপে, প্রত্যেকের একটি ব্যক্তিগত চাবি আছে।\n",
    "\n",
    "### এনক্রিপ্ট Encrypt()\n",
    "\n",
    "সুতরাং, ধরা যাক আমরা একটি ভেরিয়েবল `x`\" এনক্রিপ্ট \"করতে চেয়েছিলাম, আমরা নিম্নলিখিত পদ্ধতিতে এটি করতে পারি।\n",
    "\n",
    " > এনক্রিপশন ফ্লোটস বা আসল সংখ্যা ব্যবহার করে না তবে এটি গাণিতিক জায়গায় ঘটে [integer quotient ring](http://mathworld.wolfram.com/QuotientRing.html) যা মূলত এর মধ্যে পূর্ণসংখ্যা `0` এবং `Q-1`, যেখানে `Q` প্রধান এবং \"যথেষ্ট বড়\" যাতে স্থানটি আমাদের পরীক্ষাগুলিতে আমরা যে সমস্ত সংখ্যা ব্যবহার করি তা ধারণ করতে পারে। অনুশীলনে, একটি মান দেওয়া হয় `x` পূর্ণসংখ্যা, আমরা করি `x % Q` রিং এর মধ্যে ফিট। (এজন্যই আমরা সংখ্যা ব্যবহার করা এড়িয়ে চলি `x' > Q`)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "Q = 1234567891011"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "x = 25"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "import random\n",
    "\n",
    "def encrypt(x):\n",
    "    share_a = random.randint(-Q,Q)\n",
    "    share_b = random.randint(-Q,Q)\n",
    "    share_c = (x - share_a - share_b) % Q\n",
    "    return (share_a, share_b,  share_c)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(890804432397, -2305631655, 346069090294)"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "encrypt(x)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "আপনি এখানে দেখতে পাচ্ছেন, আমরা আমাদের পরিবর্তনশীল `x` কে 3 টি আলাদা শেয়ারে বিভক্ত করেছি, যা 3 টি পৃথক মালিককে পাঠানো যেতে পারে।\n",
    "\n",
    "### ডিক্রিপ্ট Decrypt()\n",
    "\n",
    "আমরা যদি এই 3 টি শেয়ার ডিক্রিপ্ট করতে চাইতাম, তবে আমরা কেবল তাদের একসাথে যোগ করতে পারি এবং ফলাফলের মডুলাস নিতে পারি (Mod Q)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "def decrypt(*shares):\n",
    "    return sum(shares) % Q"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "a,b,c = encrypt(25)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "25"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "decrypt(a, b, c)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "গুরুত্বপূর্ণভাবে লক্ষ করুন যে আমরা যদি মাত্র দুটি শেয়ার দিয়ে ডিক্রিপ্ট করার চেষ্টা করি তবে ডিক্রিপশনটি কার্যকর হয় না!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "778460474681"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "decrypt(a, b)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "সুতরাং, মানটি ডিক্রিপ্ট করার জন্য আমাদের সকল মালিকদের অংশ নেওয়া উচিত। এটি এই ভাবেই `shares` ব্যক্তিগত কীগুলির মতো কাজ করুন, মানটি ডিক্রিপ্ট করার জন্য অবশ্যই এগুলির সমস্ত উপস্থিত থাকতে হবে।"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Step 2: বেসিক গাণিতিক এসএমপিসি ব্যবহার করে (Basic Arithmetic Using SMPC)\n",
    "\n",
    "তবে সিকিউর মাল্টি পার্টির গণনার সত্যিকারের অসাধারণ সম্পত্তি হ'ল গণনা সম্পাদন করার ক্ষমতা **যখন ভেরিয়েবলগুলি এখনও এনক্রিপ্ট করা থাকে**। নীচে সহজ সংযোজন প্রদর্শিত যাক।"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "x = encrypt(25)\n",
    "y = encrypt(5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "def add(x, y):\n",
    "    z = list()\n",
    "    # the first worker adds their shares together\n",
    "    z.append((x[0] + y[0]) % Q)\n",
    "    \n",
    "    # the second worker adds their shares together\n",
    "    z.append((x[1] + y[1]) % Q)\n",
    "    \n",
    "    # the third worker adds their shares together\n",
    "    z.append((x[2] + y[2]) % Q)\n",
    "    \n",
    "    return z"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "30"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "decrypt(*add(x,y))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### সফলতা (Success!!!)\n",
    "\n",
    "এবং সেখানে আপনি এটা আছে! যদি প্রতিটি কর্মী (পৃথকভাবে) তাদের শেয়ারগুলি একসাথে যোগ করে, তবে ফলস্বরূপ শেয়ারগুলি সঠিক মানটিতে ডিক্রিপ্ট হবে (25 + 5 == 30). \n",
    "\n",
    "দেখা যাচ্ছে যে এসএমপিসি(SMPC) প্রোটোকল রয়েছে যা নিম্নলিখিত ক্রিয়াকলাপগুলির জন্য এই এনক্রিপ্ট করা গণনার অনুমতি দিতে পারে:\n",
    "\n",
    "- যোগ (যা আমরা সবেমাত্র দেখেছি)\n",
    "- গুণ\n",
    "- তুলনা\n",
    "\n",
    "এবং এই প্রাথমিক অন্তর্নিহিত আদিম ব্যবহার করে, আমরা নির্বিচারে গণনা সম্পাদন করতে পারি !!!\n",
    "\n",
    "পরবর্তী বিভাগে, আমরা কীভাবে এই অপারেশনগুলি সম্পাদন করতে পাই সাইফ্ট গ্রন্থাগারটি ব্যবহার করতে পারি তা শিখতে চলেছি!"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Step 3: এসএমপিসি পাইসাইফ্ট ব্যবহার করে (SMPC Using PySyft)\n",
    "\n",
    "পূর্ববর্তী বিভাগগুলিতে, আমরা এসএমপিসি-এর আশেপাশে কিছু বেসিক অন্তর্দৃষ্টিগুলি রূপরেখার কাজ করেছি বলে ধারণা করা হচ্ছে। যাইহোক, বাস্তবে আমাদের এনক্রিপ্ট করা প্রোগ্রামগুলি লেখার সময় আমরা আদিম ক্রিয়াকলাপগুলির সমস্ত নিজের হাতে লিখতে চাই না। সুতরাং, এই বিভাগে আমরা পাইসাইফ্ট ব্যবহার করে এনক্রিপ্ট করা গণনা কীভাবে করতে হবে তার মূল বিষয়গুলি নিয়ে যেতে পারি। বিশেষত, আমরা পূর্বে উল্লিখিত 3 আদিমগুলি কীভাবে করব তার উপর ফোকাস করতে যাচ্ছি: সংযোজন, গুণ এবং তুলনা।\n",
    "\n",
    "প্রথমত, আমাদের কয়েকটি ভার্চুয়াল ওয়ার্কার তৈরি করতে হবে (যা আশা করি আপনি এখন আমাদের আগের টিউটোরিয়ালগুলির সাথে পরিচিত হন)।"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "import torch\n",
    "import syft as sy\n",
    "hook = sy.TorchHook(torch)\n",
    "\n",
    "bob = sy.VirtualWorker(hook, id=\"bob\")\n",
    "alice = sy.VirtualWorker(hook, id=\"alice\")\n",
    "bill = sy.VirtualWorker(hook, id=\"bill\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### সাধারণ এনক্রিপশন / ডিক্রিপশন (Basic Encryption/Decryption)\n",
    "\n",
    "এনক্রিপশনটি(Encryption) কোনও পাইসাইফ্ট টেনসর নেওয়া এবং কল করার মতোই সহজ.share(). ডিক্রিপশন কল করার মতোই সহজ .get() ভাগ করা পরিবর্তনশীল উপর"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "x = torch.tensor([25])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([25])"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "encrypted_x = x.share(bob, alice, bill)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([25])"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "encrypted_x.get()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### এনক্রিপ্ট করা মানগুলিকে আত্মপ্রকাশ করে (Introspecting the Encrypted Values)\n",
    "\n",
    "আমরা যদি Bob, Alice এবং Bill এর কর্মীদের কাছাকাছি তাকান, আমরা যে শেয়ারগুলি তৈরি হবে তা দেখতে পাব!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{}"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "bob._objects"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [],
   "source": [
    "x = torch.tensor([25]).share(bob, alice, bill)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([3212861001891376707])"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Bob's share\n",
    "bobs_share = list(bob._objects.values())[0]\n",
    "bobs_share"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([61371170032936135])"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Alice's share\n",
    "alices_share = list(alice._objects.values())[0]\n",
    "alices_share"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([1337453846503075087])"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Bill's share\n",
    "bills_share = list(bill._objects.values())[0]\n",
    "bills_share"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "এবং যদি আমরা চাইতাম, আমরা আগে যে বিষয়গুলি নিয়ে আলোচনা করেছি সেগুলি ব্যবহার করে আমরা এই মানগুলি ডিক্রিপ্ট করতে পারি !!!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([25])"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "Q = x.child.field\n",
    "\n",
    "(bobs_share + alices_share + bills_share) % Q"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "যেমন আপনি দেখতে পাচ্ছেন, আমরা যখন ফোন করেছি`.share()` এটি কেবলমাত্র 3 টি শেয়ারে মূল্য বিভক্ত করে এবং প্রতিটি দলের কাছে একটি ভাগ প্রেরণ করে!"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# এনক্রিপ্ট করা পাটীগণিত (Encrypted Arithmetic)\n",
    "\n",
    "এবং এখন আপনি দেখতে পাচ্ছেন যে আমরা অন্তর্নিহিত মানগুলিতে গাণিতিক সম্পাদন করতে পারি! এপিআইটি(API) এমনভাবে তৈরি করা হয়েছে যাতে আমরা পাইটর্চ টেনসোর(PyTorch tensors) মতো সাধারণভাবে পাটিগণিত সম্পাদন করতে পারি।"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [],
   "source": [
    "x = torch.tensor([25]).share(bob,alice)\n",
    "y = torch.tensor([5]).share(bob,alice)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([30])"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "z = x + y\n",
    "z.get()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([20])"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "z = x - y\n",
    "z.get()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# এনক্রিপ্ট করা গুণ (Encrypted Multiplication)\n",
    "\n",
    "গুণনের জন্য আমাদের একটি অতিরিক্ত দল দরকার যারা ধারাবাহিকভাবে এলোমেলো সংখ্যা তৈরি করার জন্য দায়ী (এবং অন্য দলের কোনওটির সাথে মিলিত না হয়ে)। আমরা এই ব্যক্তিকে \"ক্রিপ্টো সরবরাহকারী/crypto provide\" বলি। সমস্ত নিবিড় উদ্দেশ্যে, ক্রিপ্টো সরবরাহকারী কেবল একটি অতিরিক্ত ভার্চুয়াল ওয়ার্কার, তবে এটি স্বীকার করা জরুরী যে ক্রিপ্টো সরবরাহকারী কোনও \"মালিক\" নন যে তার নিজের অংশীদারি নেই, তবে এমন কেউ আছেন যাকে একত্রিত করার জন্য বিশ্বাস করা উচিত নয় বিদ্যমান যে কোনও শেয়ারহোল্ডারের(shareholders) সাথে।"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [],
   "source": [
    "crypto_provider = sy.VirtualWorker(hook, id=\"crypto_provider\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [],
   "source": [
    "x = torch.tensor([25]).share(bob,alice, crypto_provider=crypto_provider)\n",
    "y = torch.tensor([5]).share(bob,alice, crypto_provider=crypto_provider)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([125])"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# multiplication\n",
    "\n",
    "z = x * y\n",
    "z.get()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "আপনি ম্যাট্রিক্স গুণও করতে পারেন"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [],
   "source": [
    "x = torch.tensor([[1, 2],[3,4]]).share(bob,alice, crypto_provider=crypto_provider)\n",
    "y = torch.tensor([[2, 0],[0,2]]).share(bob,alice, crypto_provider=crypto_provider)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[2, 4],\n",
       "        [6, 8]])"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# matrix multiplication\n",
    "\n",
    "z = x.mm(y)\n",
    "z.get()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# এনক্রিপ্ট করা তুলনা (Encrypted comparison)\n",
    "ব্যক্তিগত মূল্যগুলির মধ্যে ব্যক্তিগত তুলনা করাও সম্ভব। আমরা এখানে সিকিওরএনএন(SecureNN) প্রোটোকলে নির্ভর করি, যার বিবরণ পাওয়া যাবে [এখানে](https://eprint.iacr.org/2018/442.pdf). তুলনার ফলাফলটি একটি ব্যক্তিগত শেয়ার্ড টেনসরও।"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [],
   "source": [
    "x = torch.tensor([25]).share(bob,alice, crypto_provider=crypto_provider)\n",
    "y = torch.tensor([5]).share(bob,alice, crypto_provider=crypto_provider)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([1])"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "z = x > y\n",
    "z.get()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([0])"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "z = x <= y\n",
    "z.get()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([0])"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "z = x == y\n",
    "z.get()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([1])"
      ]
     },
     "execution_count": 35,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "z = x == y + 20\n",
    "z.get()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "আপনি max অপারেশনও করতে পারেন  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([4])"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = torch.tensor([2, 3, 4, 1]).share(bob,alice, crypto_provider=crypto_provider)\n",
    "x.max().get()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([4, 3])"
      ]
     },
     "execution_count": 37,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = torch.tensor([[2, 3], [4, 1]]).share(bob,alice, crypto_provider=crypto_provider)\n",
    "max_values, max_ids = x.max(dim=0)\n",
    "max_values.get()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# অভিনন্দন সম্প্রদায় যোগদানের সময়! (Congratulations!!! - Time to Join the Community!)\n",
    "\n",
    "এই নোটবুক টিউটোরিয়ালটি সম্পন্ন করার জন্য অভিনন্দন। আপনি যদি এটি উপভোগ করেন এবং গোপনীয়তা সংরক্ষণ, AI এবং AI সরবরাহ চেইনের (ডেটা) বিকেন্দ্রীভূত মালিকানার দিকে আন্দোলনে যোগ দিতে চান, আপনি নিম্নলিখিত উপায়ে এটি করতে পারেন।\n",
    "\n",
    "### গিটহাবে পাইসিফ্ট কে স্টার দিন (Star PySyft on GitHub)\n",
    "\n",
    "আমাদের সম্প্রদায়কে সাহায্য করার সবচেয়ে সহজ উপায় হল রিপোসিটোরি গুলোতে ষ্টার করা\n",
    " এটি আমরা যে অসাধারণ সরঞ্জামগুলি তৈরি করছি তার সচেতনতা বাড়াতে সহায়তা করে।\n",
    "\n",
    "- [Star PySyft](https://github.com/OpenMined/PySyft)\n",
    "\n",
    "### আমাদের স্ল্যাক যোগ দিন (Join our Slack!)\n",
    "\n",
    "সর্বশেষতম অগ্রগতিতে আপ টু ডেট রাখার সর্বোত্তম উপায় হ'ল আমাদের সম্প্রদায়ে যোগদান করা। আপনি ফর্মটি পূরণ করে এটি করতে পারেন [http://slack.openmined.org](http://slack.openmined.org)\n",
    "\n",
    "### একটি কোড প্রকল্পে যোগদান করুন! (Join a Code Project!)\n",
    "\n",
    "আমাদের সম্প্রদায়ে অবদান রাখার সর্বোত্তম উপায় হল কোড অবদানকারী হয়ে উঠুন! যে কোনও সময় আপনি পাইসাইফ্ট গিটহাবে ইস্যু পৃষ্ঠাতে যেতে পারেন এবং \"প্রকল্পগুলি\" এর জন্য ফিল্টার করতে পারেন। এটি আপনাকে শীর্ষ স্তরের সমস্ত টিকিট দেখিয়ে দেবে যে আপনি কোন প্রকল্পগুলিতে যোগদান করতে পারেন তার একটি ওভারভিউ দেয়! আপনি যদি কোনও প্রকল্পে যোগ দিতে না চান তবে আপনি কিছুটা কোডিং করতে চান তবে আপনি \"ভাল প্রথম ইস্যু\" চিহ্নিত গিথুব ইস্যুগুলি অনুসন্ধান করে আরও \"ওয়ান অফ\" মিনি-প্রকল্পগুলির সন্ধান করতে পারেন।\n",
    "\n",
    "- [PySyft Projects](https://github.com/OpenMined/PySyft/issues?q=is%3Aopen+is%3Aissue+label%3AProject)\n",
    "- [Good First Issue Tickets](https://github.com/OpenMined/PySyft/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22)\n",
    "\n",
    "### দান করুন (Donate)\n",
    "\n",
    "আপনার যদি আমাদের কোডবেসে অবদান রাখার সময় না থাকে তবে তবুও সমর্থন দিতে চান, আপনি আমাদের ওপেন কালেক্টিভেরও Backer হয়ে উঠতে পারেন। সমস্ত অনুদান আমাদের ওয়েব হোস্টিং এবং অন্যান্য সম্প্রদায় ব্যয় যেমন হ্যাকাথনস এবং মেটআপগুলির (hackathons and meetups!) দিকে যায়।\n",
    "\n",
    "- [Donate through OpenMined's Open Collective Page](https://opencollective.com/openmined)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
